package com.bestcem.xm.common.core.config.grpc;

import com.google.common.collect.Lists;
import io.grpc.Channel;
import io.grpc.ClientInterceptor;
import io.grpc.ClientInterceptors;
import net.devh.boot.grpc.client.channelfactory.GrpcChannelConfigurer;
import net.devh.boot.grpc.client.channelfactory.ShadedNettyChannelFactory;
import net.devh.boot.grpc.client.config.GrpcChannelsProperties;
import net.devh.boot.grpc.client.interceptor.GlobalClientInterceptorRegistry;

import java.util.List;

/**
 * @author sh.pei <sh.pei@idiaoyan.com>
 * @version v1.0
 * @date 2021/11/15 22:26
 */
public class XmShadedNettyChannelFactory extends ShadedNettyChannelFactory implements XmGrpcFactory{

    /**
     * 是否关闭
     */
    private boolean shutdown = false;

    /**
     * Creates a new GrpcChannelFactory for shaded netty with the given options.
     *
     * @param properties                      The properties for the channels to create.
     * @param globalClientInterceptorRegistry The interceptor registry to use.
     * @param channelConfigurers              The channel configurers to use. Can be empty.
     */
    public XmShadedNettyChannelFactory(GrpcChannelsProperties properties, GlobalClientInterceptorRegistry globalClientInterceptorRegistry, List<GrpcChannelConfigurer> channelConfigurers) {
        super(properties, globalClientInterceptorRegistry, channelConfigurers);
    }

    /**
     * 重写创建channel方法，返回自定义的channel
     * @param name
     * @param customInterceptors
     * @param sortInterceptors
     * @return
     */
    @Override
    public Channel createChannel(String name, List<ClientInterceptor> customInterceptors, boolean sortInterceptors) {
        return new XMManagedChannel(this, name, customInterceptors, sortInterceptors);
    }

    /**
     * 关闭
     */
    @Override
    public synchronized void close() {
        if (shutdown) {
            return;
        }
        shutdown = true;
        super.close();
    }

    /**
     * 真正创建channel的地方
     * @param name
     * @param customInterceptors
     * @param sortInterceptors
     * @return
     */
    @Override
    public Channel[] xmCreateChannel(String name, List<ClientInterceptor> customInterceptors, boolean sortInterceptors) {
        final Channel channel;
        synchronized (this) {
            if (this.shutdown) {
                throw new IllegalStateException("GrpcChannelFactory is already closed!");
            }
            channel = newManagedChannel(name);
        }
        final List<ClientInterceptor> interceptors =
                Lists.newArrayList(this.globalClientInterceptorRegistry.getClientInterceptors());
        interceptors.addAll(customInterceptors);
        if (sortInterceptors) {
            this.globalClientInterceptorRegistry.sortInterceptors(interceptors);
        }
        Channel[] ret = new Channel[2];
        ret[0] = channel;
        ret[1] = ClientInterceptors.interceptForward(channel, interceptors);
        return ret;
    }
}
